package com.ypd.shop.service.impl;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;

import com.ypd.common.constant.AuctionConstants;
import com.ypd.common.exception.auction.AuctionException;
import com.ypd.common.utils.SecurityUtils;
import com.ypd.shop.domain.AuctionItem;
import com.ypd.shop.domain.AuctionStatus;
import com.ypd.shop.domain.vo.AuctionVo;
import com.ypd.shop.service.IAuctionItemService;
import com.ypd.shop.service.IAuctionStatusService;
import com.ypd.shop.service.IPostBoxService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ypd.shop.mapper.BidMapper;
import com.ypd.shop.domain.Bid;
import com.ypd.shop.service.IBidService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 拍卖出价记录Service业务层处理
 * 
 * @author lin
 * @date 2025-02-28
 */
@Service
public class BidServiceImpl implements IBidService 
{
    @Autowired
    private BidMapper bidMapper;
    @Autowired
    private IAuctionStatusService auctionStatusService;
    @Autowired
    private IAuctionItemService auctionItemService;
    @Autowired
    private IPostBoxService postBoxService;

    /**
     * 查询拍卖出价记录
     * 
     * @param bidId 拍卖出价记录主键
     * @return 拍卖出价记录
     */
    @Override
    public Bid selectBidByBidId(String bidId)
    {
        return bidMapper.selectBidByBidId(bidId);
    }

    /**
     * 查询拍卖出价记录列表
     * 
     * @param bid 拍卖出价记录
     * @return 拍卖出价记录
     */
    @Override
    public List<Bid> selectBidList(Bid bid)
    {
        return bidMapper.selectBidList(bid);
    }

    /**
     * 新增拍卖出价记录
     * 出价事件需要注意点:
     * 是否有人同时出价(即加锁问题)
     * 
     * @param bid 拍卖出价记录
     * @return 结果
     */
    @Override
    @Transactional
    //如果正常出价成功的话,应该增加出价表,修改status状态表,可能增加postBox表
    public int insertBid(Bid bid)
    {
        AuctionStatus status = auctionStatusService.selectAuctionStatusByItemId(bid.getItemId());
        AuctionItem item = auctionItemService.selectAuctionItemByItemId(bid.getItemId());
        //使用乐观锁确保出价正确,出价是否满足要求
        //也就是进行更新status的时候,判断是否成立
        // 计算剩余时间
        // 将LocalDateTime类型转换成时间戳，并计算剩余时间
        if (item.getStatus()!= AuctionConstants.AUCTION_STATUS_BIDDING){
            throw new AuctionException(new Throwable("拍卖未开始或者已经结束"));
        }
        long endTimeMillis = status.getEndTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
        long remainTime = endTimeMillis - System.currentTimeMillis();

        if (bid.getBidPrice().compareTo(status.getCurrentPrice().add(item.getIncrement())) <0){
            //出价异常,抛出异常
            throw new AuctionException(new Throwable("已有更高出价"));
        }
        // 判断出价时间是否小于最后五分钟
        if (remainTime < 300000) { // 5分钟 = 300000毫秒
            // 如果剩余时间小于5分钟，则延长结束时间为当前时间加上5分钟
            LocalDateTime newEndTime = status.getEndTime().plusMinutes(5);
            status.setEndTime(newEndTime);
        }
        // 判断结束时间是否大于一天
        else if (remainTime > 86400000) { // 1天 = 86400000毫秒
            // 如果剩余时间大于一天，则将结束时间设置为当前时间加一天
            LocalDateTime newEndTime = LocalDateTime.now().plusDays(1);
            status.setEndTime(newEndTime);
        }
        //更新最高价和最后时间,还有最高价格的用户id
        status.setCurrentPrice(bid.getBidPrice());
        //进行判断最高价用户id是否有变化,如果有,通知(上一个出价)的
        if(status.getLeaderId()!=null){
            if (!status.getLeaderId().equals(SecurityUtils.getUserId().toString())){
                //给上一个人发通知
                List<String> list = new ArrayList<>();
                list.add(String.valueOf(status.getLeaderId()));
                postBoxService.sendMail(bid.getItemId(),list,AuctionConstants.EVENT_EXCEED_NUM);
                //换代
                status.setLeaderId(String.valueOf(SecurityUtils.getUserId()));
            }
        }else{
            //第一次拍卖的时候设定leaderId
            status.setLeaderId(String.valueOf(SecurityUtils.getUserId()));
        }

        try{
            auctionStatusService.updateAuctionStatus(status);
        }catch (Exception e){
            throw new AuctionException(new Throwable("请查看最新出价情况,进行重新出价"));
        }
        bid.setUserId(SecurityUtils.getUserId());
        return bidMapper.insertBid(bid);
    }

    /**
     * 修改拍卖出价记录
     * 
     * @param bid 拍卖出价记录
     * @return 结果
     */
    @Override
    public int updateBid(Bid bid)
    {
        return bidMapper.updateBid(bid);
    }

    /**
     * 批量删除拍卖出价记录
     * 
     * @param bidIds 需要删除的拍卖出价记录主键
     * @return 结果
     */
    @Override
    public int deleteBidByBidIds(String[] bidIds)
    {
        return bidMapper.deleteBidByBidIds(bidIds);
    }

    /**
     * 删除拍卖出价记录信息
     * 
     * @param bidId 拍卖出价记录主键
     * @return 结果
     */
    @Override
    public int deleteBidByBidId(String bidId)
    {
        return bidMapper.deleteBidByBidId(bidId);
    }
}
